昨天做出來了基本的雛形,今天就來完善吧,目前比較嚴重的問題是在移動的時候,字體是可以被移出去邊界外
為了解決這個問題, fabric
提供了很多事件可以讓我們使用,我們可以針對個別物件進行監聽,也可以在最外層的 canvas
統一監聽。因為我們物件沒有需要特別處理,所以就統一在外面監聽,接著使用 getBoundingRect
方法獲得左右距離及寬高。
這邊的
getBoundingRect
方法是fabirc
提供的唷,雖然跟原生的回傳值幾乎一樣。
接著就是做邊界判斷,當超出上下或左右的時候移到最近的邊界點。最後記得使用 renderAll
。
this.fabricCanvas.on('object:moving', e => {
const obj = e.target
obj.setCoords()
const { top, left, width, height } = obj.getBoundingRect()
if (top < 0) {
obj.top = 0
}
if (top + height > this.height) {
obj.top = this.height - height
}
if (left < 0) {
obj.left = 0
}
if (left + width > this.width) {
obj.left = this.width - width
}
this.fabricCanvas.renderAll()
})
到這邊,邊界的問題就解決了,接著加入新增文字鈕,並且讓文字置中,計算出間距避免所有的文字都擠在一起,在設定 top
的時候會依據現在的字多寡來算出間距,並且在最後使用 centerH
來將水平位置移到中間。
const editText = new fabric.IText('點擊編輯', {
top: 10 + this.editTexts.length * 50,
fill: '#ffffff',
stroke: '#000000',
fontSize: 40,
fontFamily: 'Microsoft JhengHei, PMingLiU, sans-serif'
})
this.editTexts.push(editText)
this.fabricCanvas.add(editText)
editText.centerH()
這樣一直新增也不會覆蓋到原本的文字。看一下到現在的成果吧
接著實作一個文字替換顏色的功能
<div class="picker">
fill:
<input
type="color"
:value="item.fill"
@change="(e) => colorChange(e, index)"
/>
</div>
colorChange(e, index) {
const target = this.editTexts[index]
target.set('fill', e.target.value)
this.render()
}
這邊直接使用了原生的 color picker,不過這也是第一次使用,也是在查資料的時候才發現原生就有提供這個功能。這邊基本上功能就只剩下載囉,下載其實基本上跟之前使用方法一樣。
downloadImg() {
const url = this.fabricCanvas.toDataURL({
format: 'png'
})
const link = document.createElement('a')
link.href = url
link.download = 'yourname.png'
link.click()
}
但在使用上會出現 "SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported."
主要是因為我們這次的圖片來源是來自跨域下載,所以出於安全性原因被阻擋,為了避免這個現象,我們在讀取圖片的時候設定第三個參數
{
crossOrigin: 'Anonymous'
}
到這邊就大功告成囉,可以成功下載,來看一下最後的成品吧
這幾篇介紹了這個好用的 Canvas
處理套件,讓我們不必跟原生的 api
做溝通,可以使用各種方便的封裝方法,如果有使用互動的需求推薦使用這個套件,那就明天見囉!